#pragma once

#include "EventLoop.h"
#include "Acceptor.h"
#include "InetAddress.h"
#include "EventLoopThreadPool.h"
#include "Callbacks.h"
#include "TcpConnection.h"
#include "Buffer.h"

#include <unordered_map>


// 对外提供用于服务器编程的类
class TcpServer : noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop*)>;

    enum Option
    {
        kNoReusePort,
        kReusePort
    };

    TcpServer(EventLoop* loop, const InetAddress& listenAddr, const std::string& nameArg, Option option = kNoReusePort);
    ~TcpServer();

    void setThreadInitCallback(const ThreadInitCallback& cb) { m_threadInitCallback = cb; }
    void setConnectionCallback(const ConnectionCallback& cb) { m_connectionCallback = cb; }
    void setMessageCallback(const MessageCallback& cb) { m_messageCallback = cb; }
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) { m_writeCompleteCallback = cb; }

    // 设置底层的线程和subloop的个数
    void setThreadNum(int numThreads);

    // 开启服务器进行监听
    void start();

private:
    // 有新的客户端连接时，Acceptor会接受连接，执行回调操作
    void newConnection(int sockfd, const InetAddress& peerAddr);
    void removeConnection(const TcpConnectionPtr& conn);
    void removeConnectionInLoop(const TcpConnectionPtr& conn);

private:
    EventLoop* m_loop;  // baseloop(mainloop) 用户自定义的loop

    const std::string m_ipPort;
    const std::string m_name;

    std::unique_ptr<Acceptor> m_acceptor;   // 运行在mainloop，任务就是监听新连接
    std::shared_ptr<EventLoopThreadPool> m_threadPool;  // one loop per thread

    ConnectionCallback m_connectionCallback; // 有新连接时的回调
    MessageCallback m_messageCallback;  // 有读写消息时的回调
    WriteCompleteCallback m_writeCompleteCallback; // 消息发送完成以后的回调

    ThreadInitCallback m_threadInitCallback; // loop线程初始化的回调

    std::atomic_int m_started;

    int m_nextConnId;

    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;
    ConnectionMap m_connections; // 保存所有的连接
};